<template>
    <div>
        <a-table :columns="columns" :data-source="data" :scroll="{ y: 1500 }" :loading="loading" :pagination="false">
            <template #bodyCell="{ column, record }">
                <template v-if="column.dataIndex === 'column_name'">
                    <a-input v-model:value="record.column_name" />
                </template>

                <template v-if="column.dataIndex === 'type'">
                    <a-select v-model:value="record.type" style="width: 100%" @change="(val: string) => handleTypeChange(record, val)">
                        <a-select-option v-for="item in typeOptions" :key="item.value" :value="item.value">
                            {{ item.label }}
                        </a-select-option>
                    </a-select>
                </template>

                <template v-if="column.dataIndex === 'length'">
                    <div style="display: flex; align-items: center; gap: 4px;">
                        <a-input-number v-model:value="record.length" :min="0" :max="getTypeMaxLength(record.type)" style="width: 70px" @change="(val: number | null) => handleLengthChange(record, val)" />
                        <template v-if="['decimal','float','double'].includes(record.type)">
                            <span>,</span>
                            <a-input-number v-model:value="record.scale" :min="0" :max="30" style="width: 50px" @change="(val: number | null) => handleScaleChange(record, val)" />
                        </template>
                    </div>
                </template>

                <template v-if="column.dataIndex === 'unsigned'">
                    <a-checkbox :checked="record.unsigned" @change="(e: Event) => handleUnsignedChange(record, (e.target as HTMLInputElement).checked)" />
                </template>

                <template v-if="column.dataIndex === 'is_nullable'">
                    <a-checkbox :checked="record.is_nullable === 'NO'" @change="(e: Event) => handleNullableChange(record, (e.target as HTMLInputElement).checked)" />
                </template>

                <template v-if="column.dataIndex === 'column_default'">
                    <!-- <span>{{ record.column_default === null ? '' : record.column_default }}</span> -->
                    <a-input v-model:value="record.column_default" />
                </template>

                <template v-if="column.dataIndex === 'column_key'">
                    <span @click="handleKeyClick(record)" style="cursor:pointer;">
                        <span v-if="record.column_key === 'PRI'" style="color: #1677ff; font-weight: bold;">主键</span>
                        <span v-else-if="record.column_key === 'UNI'" style="color: #722ed1; font-weight: bold;">唯一</span>
                        <span v-else-if="record.column_key === 'MUL'" style="color: #52c41a; font-weight: bold;">索引</span>
                        <span v-else style="color: #ccc;">无</span>
                    </span>
                </template>

                <template v-if="column.dataIndex === 'column_type'">
                    <span>{{ record.column_type }}</span>
                </template>

                <template v-if="column.dataIndex === 'extra'">
                    <a-switch 
                        :checked="record.extra === 'auto_increment'" 
                        @change="(checked: boolean) => handleAutoIncrementChange(record, checked)"
                        :disabled="record.column_key !== 'PRI' || !['int', 'tinyint', 'bigint', 'smallint', 'mediumint'].includes(record.type)"
                    />
                </template>

                <template v-if="column.dataIndex === 'column_coment'">
                    <a-input v-model:value="record.column_coment" />
                </template>

                <template v-if="column.dataIndex === 'actions'">
                    <a-space>
                        <a-button type="link" danger @click="handleDelete(record)">删除</a-button>
                        <a-button v-if="record === data[data.length - 1]" type="link" @click="handleAdd">新增</a-button>
                    </a-space>
                </template>
            </template>
        </a-table>
    </div>
</template>

<script setup lang="ts">
import request from '@/utils/request'
import { ref, watch } from 'vue'

const props = defineProps<{
    table_name: string
}>()

const typeOptions = [
    { value: 'int', label: 'int', defaultLimit: 11 },
    { value: 'tinyint', label: 'tinyint', defaultLimit: 4 },
    { value: 'varchar', label: 'varchar', defaultLimit: 255 },
    { value: 'char', label: 'char', defaultLimit: 255 },
    { value: 'datetime', label: 'datetime', defaultLimit: 0 },
    { value: 'timestamp', label: 'timestamp', defaultLimit: 0 },
    { value: 'text', label: 'text', defaultLimit: 0 },
    { value: 'float', label: 'float', defaultLimit: 11 },
    { value: 'double', label: 'double', defaultLimit: 11 },
    { value: 'decimal', label: 'decimal', defaultLimit: 11 },
    // 可根据需要补充
]

const typeMaxLengthMap: Record<string, number> = {
    int: 11,
    tinyint: 4,
    varchar: 255,
    char: 255,
    float: 11,
    double: 11,
    decimal: 11,
    text: 0,
    datetime: 0,
    timestamp: 0
}

function getTypeMaxLength(type: string) {
    return typeMaxLengthMap[type] || 255
}

const columns = [
    {
        title: '字段',
        dataIndex: 'column_name',
    },
    {
        title: '类型',
        dataIndex: 'type',
        width: 180,
    },
    {
        title: '长度',
        dataIndex: 'length',
        width: 180,
    },
    {
        title: '无符号',
        dataIndex: 'unsigned',
        width: 80,
        align: 'center',
    },
    {
        title: '不是 null',
        dataIndex: 'is_nullable',
        width: 100,
        align: 'center',
    },
    {
        title: '默认值',
        dataIndex: 'column_default',
        width: 150,
    },
    {
        title: '键',
        dataIndex: 'column_key',
        width: 80,
        align: 'center',
    },
    {
        title: '是否递增',
        dataIndex: 'extra',
        width: 100,
        align: 'center',
    },
    {
        title: '字段类型',
        dataIndex: 'column_type',
        width: 150,
    },
    {
        title: '注释',
        dataIndex: 'column_coment',
    },
    {
        title: '操作',
        dataIndex: 'actions',
        width: 220,
    }
]

const api = (params?: any) => request.get({ url: '/adminapi/system.setting.database/tableField', params: { ...params, table_name: props.table_name } })
const emits = defineEmits<{
    (e: 'change:table_name', value: any): void
}>()
const data = ref<any[]>([])
const loading = ref(false)
const isLoaded = ref(false)

function parseColumnType(columnType: string) {
    // 例：decimal(10,2) 或 int(11) unsigned
    const typeMatch = columnType.match(/^\w+/)
    const decimalMatch = columnType.match(/\((\d+),(\d+)\)/)
    const lengthMatch = columnType.match(/\((\d+)\)/)
    const unsigned = columnType.includes('unsigned')
    if (decimalMatch) {
        return {
            type: typeMatch ? typeMatch[0] : columnType,
            length: decimalMatch[1],
            scale: decimalMatch[2],
            unsigned
        }
    }
    return {
        type: typeMatch ? typeMatch[0] : columnType,
        length: lengthMatch ? lengthMatch[1] : '',
        scale: '',
        unsigned
    }
}

function mergeColumnType(type: string, length: string, unsigned: boolean, scale?: string) {
    let result = type
    if (["decimal","float","double"].includes(type)) {
        if (length) {
            result += `(${length}${scale !== undefined && scale !== '' ? ',' + scale : ''})`
        }
    } else if (length && getTypeMaxLength(type) > 0) {
        result += `(${length})`
    }
    if (unsigned) {
        result += ' unsigned'
    }
    return result
}

function handleTypeChange(record: any, val: string) {
    record.type = val
    // 类型变更时直接赋默认长度
    const option = typeOptions.find(item => item.value === val)
    const defaultLen = option ? option.defaultLimit : getTypeMaxLength(val)
    if (getTypeMaxLength(val) > 0) {
        record.length = String(defaultLen)
    } else {
        record.length = ''
    }
    if (["decimal","float","double"].includes(val)) {
        record.scale = record.scale || '0'
    } else {
        record.scale = ''
    }
    record.column_type = mergeColumnType(record.type, record.length, record.unsigned, record.scale)
}

function handleUnsignedChange(record: any, checked: boolean) {
    record.unsigned = checked
    record.column_type = mergeColumnType(record.type, record.length, checked, record.scale)
}

function handleLengthChange(record: any, val: number | null) {
    record.length = val ? String(val) : ''
    record.column_type = mergeColumnType(record.type, record.length, record.unsigned, record.scale)
}

function handleScaleChange(record: any, val: number | null) {
    record.scale = val ? String(val) : ''
    record.column_type = mergeColumnType(record.type, record.length, record.unsigned, record.scale)
}

function handleNullableChange(record: any, checked: boolean) {
    record.is_nullable = checked ? 'NO' : 'YES'
    // 这里不影响 column_type，但如有需要可在此合并
}

function handleKeyClick(record: any) {
    const oldKey = record.column_key;
    
    if (record.column_key === 'PRI') {
        record.column_key = 'UNI';
        // 如果从主键变成非主键，且是自动递增，则取消自动递增
        if (record.extra === 'auto_increment') {
            record.extra = '';
        }
    } else if (record.column_key === 'UNI') {
        record.column_key = 'MUL';
    } else if (record.column_key === 'MUL') {
        record.column_key = '';
    } else {
        record.column_key = 'PRI';
    }

    emits('change:table_name', data.value);
}

function handleAutoIncrementChange(record: any, checked: boolean) {
    record.extra = checked ? 'auto_increment' : '';
    // 如果设置为自动递增，必须是主键
    if (checked && record.column_key !== 'PRI') {
        record.column_key = 'PRI';
    }
    // 触发数据变更，确保将更改发送到后端
    emits('change:table_name', data.value);
}

// 加载数据
const loadData = async () => {
    if (!props.table_name || loading.value) return
    loading.value = true
    try {
        const res = await api()
        // 解析 column_type
        data.value = (res || []).map((item: any) => {
            const parsed = parseColumnType(item.column_type || '')
            return {
                ...item,
                ...parsed,
                // 确保 extra 字段正确传递
                extra: item.extra || ''
            }
        })
        isLoaded.value = true
        emits('change:table_name', data.value)
    } finally {
        loading.value = false
    }
}

// 监听 table_name 变化
watch(
    () => props.table_name,
    (newVal) => {
        if (newVal) {
            isLoaded.value = false
            loadData()
        }
    },
    { immediate: true }
)

// 暴露刷新方法
defineExpose({
    refresh: loadData,
    isLoaded: () => isLoaded.value
})

function handleDelete(record: any) {
    const index = data.value.findIndex(item => item === record)
    if (index > -1) {
        data.value.splice(index, 1)
        emits('change:table_name', data.value)
    }
}

function handleAdd() {
    const newField = {
        column_name: '',
        type: 'varchar',
        length: '255',
        scale: '',
        unsigned: false,
        is_nullable: 'YES',
        column_default: '',
        column_coment: '',
        column_key: '',
        extra: '',
        column_type: 'varchar(255)'
    }
    data.value.push(newField)
    emits('change:table_name', data.value)
}
</script>
